7.2 子表达式的嵌套

子表达式允许嵌套。事实上,子表达式允许多重嵌套,这种嵌套的层次在理论上没有限制,但在实际工作中还是应该遵循适可而止的原则。

多重嵌套的子表达式可以构造出功能极其强大的正则表达式来,但那难免会让模式变得难以阅读和理解,而这也正是很多人觉得正则表达式难以学习和掌握的原因之一。这种表面现象掩盖了这样一个事实:绝大多数嵌套子表达式都没有它们看上去那么复杂。

为了演示嵌套子表达式的用法,我们再去看看刚才那个匹配 IP 地址的例子。下面是我们刚才使用的模式(先是一个连续重复 3 次的子表达式,然后是最后一组数字):

这个模式的使用效果显而易见,但它看起来比我们之前使用的 \d{1,3}(\.\d{1,3}){3} 要复杂的多。它和 \d{1,3}(\.\d{1,3}){3} 的构成是一样的, (25[0-5]|2[0-4]\d|1\d{2}|\d{1,2}) 匹配前面一级数字, (\.(25[0-5]|2[0-4]\d|1\d{2}|\d{1,2})){3} 匹配点和后面和一组数字并重复 3 次。

它的构成并不难解理,它真正匹配需要的数字且排除不需要的数字的地方在于 (25[0-5]|2[0-4]\d|1\d{2}|\d{1,2}) ,这部分看起来复杂,但它是由多个子表达式组成,我们只要把它拆解就可以清楚它的含义。

这部分由 25[0-5]2[0-4]1\d{2}\d{1,2} 四个子表达式组成,这四个子表达式刚好对应我们上面分析的 IPV4 的四条规则。

  • 25[0-5] :匹配任何一个以 25 开头、第 3 位数字在 0~5 之间的 3 位数字。
  • 2[0-4] :匹配任何一个以 2 开头、第 2 位数字在 0~4 之间的 3 位数字。
  • 1\d{2} :匹配任何一个以 1 开头的 3 位数字。
  • \d{1,2} :匹配任何一个 1 位或 2 位数字。
发表评论